package cn.com.main;

import com.alibaba.excel.annotation.ExcelProperty;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import cn.com.bean.MedicalWt4ExcelUploadReq;

public class ClassGenerator {

    public static void main(String[] args) throws Exception {
        generateClasses(MedicalWt4ExcelUploadReq.class);
    }

    public static void generateClasses(Class<?> clazz) throws Exception {
        Field[] fields = clazz.getDeclaredFields();
        StringBuilder normalClassBuilder = new StringBuilder();
        StringBuilder annotatedClassBuilder = new StringBuilder();
        StringBuilder conversionMethodsBuilder = new StringBuilder();

        normalClassBuilder.append("@Data\npublic class NormalClass {\n");
        annotatedClassBuilder.append("@Data\npublic class AnnotatedClass {\n");

        Map<String, String> annotatedFields = new HashMap<>();

        for (Field field : fields) {
            String fieldName = field.getName();
            String fieldType = field.getType().getSimpleName();

            normalClassBuilder.append("    private ").append(fieldType).append(" ").append(fieldName).append(";\n");

            ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
            if (annotation != null) {
                String annotatedFieldName = annotation.value()[0];
                annotatedFields.put(annotatedFieldName, fieldName);
                annotatedClassBuilder.append("    private ").append(fieldType).append(" ").append(annotatedFieldName).append(";\n");
            }
        }

        normalClassBuilder.append("}\n");
        annotatedClassBuilder.append("}\n");

        generateConversionMethods(conversionMethodsBuilder, annotatedFields);

        //写入文件中
        String normalClassName = "NormalClass";
        String annotatedClassName = "AnnotatedClass";
        String conversionMethodsClassName = "Converter";

        String normalClassFilePath = "src/main/java/cn/com/bean/" + normalClassName + ".java";
        String annotatedClassFilePath = "src/main/java/cn/com/bean/" + annotatedClassName + ".java";
        String conversionMethodsFilePath = "src/main/java/cn/com/main/" + conversionMethodsClassName + ".java";

        writeToFile(normalClassBuilder.toString(), normalClassFilePath);
        writeToFile(annotatedClassBuilder.toString(), annotatedClassFilePath);
        writeToFile(conversionMethodsBuilder.toString(), conversionMethodsFilePath);
    }

    private static void writeToFile(String content, String filePath) throws Exception {
        java.io.FileWriter writer = new java.io.FileWriter(filePath);
        writer.write(content);
        writer.close();
    }

    private static void printClasses(StringBuilder normalClassBuilder, StringBuilder annotatedClassBuilder, StringBuilder conversionMethodsBuilder) {
        System.out.println(normalClassBuilder.toString());
        System.out.println(annotatedClassBuilder.toString());
        System.out.println(conversionMethodsBuilder.toString());
    }

    private static void generateConversionMethods(StringBuilder builder, Map<String, String> annotatedFields) {
        builder.append("public class Converter {\n");

        // toNormalClass method
        builder.append("    public static NormalClass toNormalClass(OriginalClass original) {\n");
        builder.append("        NormalClass normal = new NormalClass();\n");
        for (String fieldName : annotatedFields.values()) {
            builder.append("        normal.set").append(capitalize(fieldName))
                   .append("(original.get").append(capitalize(fieldName)).append("());\n");
        }
        builder.append("        return normal;\n    }\n");

        // toAnnotatedClass method
        builder.append("    public static AnnotatedClass toAnnotatedClass(OriginalClass original) {\n");
        builder.append("        AnnotatedClass annotated = new AnnotatedClass();\n");
        for (Map.Entry<String, String> entry : annotatedFields.entrySet()) {
            builder.append("        annotated.set").append(entry.getKey())
                   .append("(original.get").append(capitalize(entry.getValue())).append("());\n");
        }
        builder.append("        return annotated;\n    }\n");

        // fromNormalClass method
        builder.append("    public static OriginalClass fromNormalClass(NormalClass normal, OriginalClass original) {\n");
        for (String fieldName : annotatedFields.values()) {
            builder.append("        original.set").append(capitalize(fieldName))
                   .append("(normal.get").append(capitalize(fieldName)).append("());\n");
        }
        builder.append("        return original;\n    }\n");

        // fromAnnotatedClass method
        builder.append("    public static OriginalClass fromAnnotatedClass(AnnotatedClass annotated, OriginalClass original) {\n");
        for (Map.Entry<String, String> entry : annotatedFields.entrySet()) {
            builder.append("        original.set").append(capitalize(entry.getValue()))
                   .append("(annotated.get").append(entry.getKey()).append("());\n");
        }
        builder.append("        return original;\n    }\n");

        builder.append("}\n");
    }

    private static String capitalize(String str) {
        if (str == null || str.length() == 0) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }
}
